package com.ruoyi.core.util;

import com.ruoyi.core.exception.RunException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wanghao 913351190@qq.com
 * @create 2022/7/13 9:48
 */
public class RequestContextUtil {

    public static HttpServletRequest getRequest() {
        try {
            if (RequestContextHolder.getRequestAttributes() != null) {
                return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            }
            return null;
        } catch (Throwable e) {
            return null;
        }
    }

    public static String getAppId(HttpServletRequest request) {
        return getParam(request, "app_id");
    }

    public static String getAppSecret(HttpServletRequest request) {
        return getParam(request, "app_secret");
    }

    public static String getClient(HttpServletRequest request) {
        return getParam(request, "client");
    }

    public static String getServiceId(HttpServletRequest request) {
        return getParam(request, "service_id");
    }

    public static String getSign(HttpServletRequest request) {
        return getParam(request, "sign");
    }

    public static String getToken(HttpServletRequest request) {
        String token = getParam(request, "token");
        if (StringUtils.isEmpty(token)) {
            token = getParam(request, "Authorization");
        }
        if (StringUtils.isEmpty(token)) {
            token = getParam(request, "X-Access-Token");
        }
        if (!StringUtils.isEmpty(token)) {
            token = token.trim();
        }
        if (!StringUtils.isEmpty(token) && token.startsWith("\"") && token.endsWith("\"")) {
            token = token.substring(1, token.length() - 1);
        }
        if (!StringUtils.isEmpty(token) && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        return token;
    }

    public static String getRequestId(HttpServletRequest request) {
        return getParam(request, "requestId");
    }

    public static boolean getEncrypt(HttpServletRequest request) {
        String encrypt = getParam(request, "encrypt");
        return (StringUtils.isEmpty(encrypt) || !encrypt.equalsIgnoreCase("false"));
    }

    public static String getRequestIp(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        String ip = request.getHeader("X-Real-IP");
        if (StringUtils.isEmpty(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String getRequestBrowser(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        String ua = request.getHeader("User-Agent");
        return ua;
    }

    public static String getRequestUrl(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        return request.getRequestURI();
    }

    public static String getRequestBody(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        try {
            try (ServletInputStream inputStream = request.getInputStream()) {
                if (inputStream != null) {
                    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = inputStream.read(buffer)) > 0) {
                            byteArrayOutputStream.write(buffer, 0, len);
                        }
                        return byteArrayOutputStream.toString();
                    }
                } else {
                    return null;
                }
            }
        } catch (Exception e) {
            throw new RunException("获取参数异常：" + e.getMessage());
        }
    }

    public static Map<String, String> getRequestParam(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        try {
            Map<String, String> parmMap = new HashMap<>();
            Enumeration<String> a = request.getParameterNames();
            String parm = null;
            String val = "";
            while (a.hasMoreElements()) {
                //参数名
                parm = a.nextElement();
                //值
                val = request.getParameter(parm);
                parmMap.put(parm, val);
            }
            return parmMap;
        } catch (Exception e) {
            throw new RunException("获取参数异常：" + e.getMessage());
        }
    }


    private static String getParam(HttpServletRequest request, String key) {
        if (request != null) {
            String paramName = getParamNameFromParam(request, key);
            if (!StringUtils.isEmpty(paramName)) {
                return request.getParameter(paramName);
            }
            paramName = getParamNameFromHead(request, key);
            if (!StringUtils.isEmpty(paramName)) {
                return request.getHeader(paramName);
            }
        }
        return null;
    }

    private static String getParamNameFromParam(HttpServletRequest request, String key) {
        Enumeration<String> a = request.getParameterNames();
        String name = null;
        while (a.hasMoreElements()) {
            name = a.nextElement();
            if (name.equalsIgnoreCase(key)) {
                return name;
            } else if (name.replace("_", "").equalsIgnoreCase(key.replace("_", ""))) {
                return name;
            }
        }
        return null;
    }

    private static String getParamNameFromHead(HttpServletRequest request, String key) {
        Enumeration<String> a = request.getHeaderNames();
        String name = null;
        while (a.hasMoreElements()) {
            name = a.nextElement();
            if (name.equalsIgnoreCase(key)) {
                return name;
            } else if (name.replace("_", "").equalsIgnoreCase(key.replace("_", ""))) {
                return name;
            }
        }
        return null;
    }

    public static HttpServletResponse getResponse() {
        try {
            if (RequestContextHolder.getRequestAttributes() != null) {
                return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            }
            return null;
        } catch (Throwable e) {
            return null;
        }
    }


}
